package org.jiucheng.magpiebridge.server.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.text.MessageFormat;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jiucheng.magpiebridge.server.aio.proxy.http11.Http11Proxy;
import org.jiucheng.magpiebridge.util.Cfg;
import org.jiucheng.magpiebridge.util.ThreadManager;

/**
 * 
 * @author jiucheng
 *
 */
public class Server {
    private static final Logger LOGGER = Logger.getLogger(Server.class.getName());
    private static final Object wait = new Object();
    
    public static void main(String[] args) throws IOException, InterruptedException {
        Cfg.loadProperties(Server.class);
        
        AsynchronousChannelGroup group = AsynchronousChannelGroup.withThreadPool(ThreadManager.singleton());
        final AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open(group);
        server.setOption(StandardSocketOptions.SO_REUSEADDR, true);
        server.setOption(StandardSocketOptions.SO_RCVBUF, 8 * 1024 * 1024);
        
        server.bind(new InetSocketAddress(Cfg.getServerIp(), Cfg.getServerPort()));
        server.accept(server, new ServerEstablishmentCompletionHandler());
        
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            public void run() {
                if (LOGGER.isLoggable(Level.INFO)) {
                    LOGGER.log(Level.INFO, "Server close");
                }
                try {
                    server.close();
                } catch (IOException e) {
                    if (LOGGER.isLoggable(Level.SEVERE)) {
                        LOGGER.log(Level.SEVERE, "close", e);
                    }
                }
            }
        }));
        if (LOGGER.isLoggable(Level.INFO)) {
            LOGGER.log(Level.INFO, MessageFormat.format("Server started({0}:{1})", Cfg.getServerIp(), Integer.toString(Cfg.getServerPort())));
        }
        
        Http11Proxy.start();
        
        synchronized (wait) {
            wait.wait();
        }
    }
}
